﻿using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using Kele.Activity.Core;
using Kele.Activity.Helper;
using Kele.Activity.Models;
using MySql.Data.MySqlClient;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
 using Kele.Repository;
namespace Kele.Activity
{
    public  class RecordService
    {        protected readonly string _connectionString = AppConfig.Setting.DefaultConnectionString;
        protected static readonly Func<DbConnection> ConnectionFactory = () => new MySqlConnection(AppConfig.Setting.DefaultConnectionString);

        private async Task<IEnumerable<MerchantStore>> GetStoreList(int merchant_id)
        {
            const string key = "activity_form_list";

            var ret = await AppCache.CacheStrategy.GetAsync<IEnumerable<MerchantStore>>(key);
            if (ret != null) return ret;

            using (var connection = ConnectionFactory())
            {
                const string sql = "SELECT * FROM kl_merchant_store WHERE id=@merchant_id ORDER BY id DESC ";
                ret = await connection.QueryAsync<MerchantStore>(sql, new { merchant_id });
                await AppCache.CacheStrategy.SetAsync(key, ret);
                return ret;
            }
        }

        public async Task<IEnumerable<Record>> GetRecordListAsync(int activity_id, int take = 10, int skip = 0, string mobile = "")
        {
            var activity = await AppService.Activity.GetActivityAsync(activity_id);
            var formList = await AppService.Form.GetFormListAsync();
            var form = formList.First(f => f.Id == activity.FormId);
            var key = form.Key; //register, skill, group_buy, bargain_pay, vote, prize_draw, million_group, card_collect

            using (var connection = ConnectionFactory())
            {
                var sqlWhere = new StringBuilder();
                sqlWhere.Append("WHERE activity_id = @activity_id");
                if (!string.IsNullOrWhiteSpace(mobile)) sqlWhere.Append(" AND mobile =@mobile");

                //activity_id, order_id, openid, num, mobile, `name`, `fields`, `status` created, scan_user, pay_time, end_time, total_fee
                var sql = new StringBuilder();
                sql.Append("  SELECT * FROM kl_activity_record ").Append(sqlWhere)
                    .Append(" ORDER BY created DESC LIMIT @take OFFSET @skip;")
                    .Append(" SELECT count(*) FROM kl_activity_record ").Append(sqlWhere);

                var orders = await connection.QueryAsync<Record>(sql.ToString(), new { activity_id, mobile, take, skip });
                if (key != "group_buy")
                {
                }
                return orders;
            }
        }

        public async Task<Record> GetRecordByUserIdAsync(int activity_id, string user_id)
        {
            using var connection = ConnectionFactory();
            var sql = new StringBuilder();
            sql.Append("SELECT * FROM kl_activity_record  WHERE id= @activity_id AND user_id =@user_id");
            return await connection.QueryFirstOrDefaultAsync<Record>(sql.ToString(), new { activity_id, user_id });
        }

        public async Task<Record> GetRecordByOrderIdAsync(int activity_id, string order_id)
        {
            using var connection = ConnectionFactory();
            var sql = new StringBuilder();
            sql.Append("SELECT * FROM kl_activity_record WHERE activity_id =@activity_id AND order_id=@order_id; ");
            var record = await connection.QueryFirstOrDefaultAsync<Record>(sql.ToString(), new { activity_id, order_id });
            var activity = await AppService.Activity.GetActivityAsync(activity_id);
            record.body = activity.Title;
            return record;
        }


        public async Task<dynamic> GetRecordDetailAsync(int activity_id, string order_id)
        {
            var activity = await AppService.Activity.GetActivityAsync(activity_id);

            var formList = await AppService.Form.GetFormListAsync();
            var form = formList.First(f => f.Id == activity.FormId);
            var fields = activity.Fields;

            using var connection = ConnectionFactory();
            //activity_id, order_id, openid, num, mobile, `name`, `fields`, `status` created, scan_user, pay_time, end_time, total_fee
            var sql = new StringBuilder();
            sql.Append("SELECT * FROM kl_activity_record WHERE activity_id =@activity_id AND order_id=@order_id; ");
            var record = await connection.QueryFirstOrDefaultAsync<Record>(sql.ToString(), new { activity_id, order_id });

            var ret = new List<dynamic>();
            var store_charge = 0m;
            //part 1 报名信息
            var group_name = "报名信息";
            var items = new List<RecordAttribute>
                {
                    new RecordAttribute {name = "报名序号", value = record.sort},
                    new RecordAttribute {name = "报名时间", value = record.created },
                    new RecordAttribute {name = "用户姓名", value = record.name},
                    new RecordAttribute {name = "用户电话", value = record.mobile}                              
                };
            var attributes = record.fields.ToJArray().Select((t, i) => new RecordAttribute { name = fields.ToJArray()?[i]?["label"]?.ToString(), value = t["value"] });
            items.AddRange(attributes);
            ret.Add(new { group_name, items });

            group_name = "活动信息";   //part 1.1 拼团信息/秒杀信息/砍价信息
            items = new List<RecordAttribute>
                {
                    new RecordAttribute {name = "活动类型", value = form.Alias},
                };
            switch (form.Key)
            {
                case "register":
                    if (activity.PrePrice > 0)
                    {
                        if (activity.Price != null)
                            store_charge = (decimal)activity.Price * record.num - record.pay_fee;
                    }
                    break;

                case "seckill":
                    break;

                case "group_buy":
                    break;

                case "bargain_buy":
                    break;

                case "vote":
                    break;

                case "prize_draw":
                    break;

                case "million_group":
                    break;

                case "card_collect":
                    break;

                default:
                    break;
            }
            ret.Add(new { group_name, items });

            group_name = "订单信息";
            items = new List<RecordAttribute>
                 {
                     new RecordAttribute {name = "支付金额", value = record.pay_fee},
                     new RecordAttribute {name = "购买数量", value = record.num},
                     new RecordAttribute {name = "到店支付", value = store_charge},
                     new RecordAttribute{name = "支付状态", value = AppService.Activity.Activity_Record_status_Mapping[record.status]},
                     new RecordAttribute{name = "核销状态", value = string.IsNullOrWhiteSpace(record.verfiy_uid) ? "已核销" : "未核销"}
                 };
            ret.Add(new { group_name, items });
            return ret;
        }

        public async Task<dynamic> H5_CreateRecordAsync(int activity_id, string user_id,string json)
        {
            var data = JObject.Parse(json);
            var activity = await AppService.Activity.GetActivityAsync(activity_id);
            var order_id  = AppUtility.GetOrderId(activity.MerchantId);
            var record = new Record
            {
                activity_id = activity_id,
                form_id = activity.FormId,
                order_id = order_id,
                name = data["name"]?.Value<string>()?? "",
                mobile = data["mobile"]?.Value<string>(),
                fields = data["fields"]?.ToString(Formatting.None),
                num = data["num"]?.Value<int>() ?? 1,
                pay_fee = data["pay_fee"]?.Value<decimal>() ?? 0,
                user_id = user_id,
                status = activity.Price == 0 ? Activity_Record_Status.free : Activity_Record_Status.unpaid,//支付状态，0=未支付 1=已支付 2=免费 4=退款
                flag = Activity_Record_Flag.none,
                props = data["props"]?.ToString(Formatting.None),
                role = 0,              
                created = DateTime.Now
            };

            using var connection = ConnectionFactory();
            var sql = new StringBuilder();
            sql.Append("SELECT max(sort) FROM kl_activity_record where activity_id =@activity_id;");
            var sort = await connection.ExecuteScalarAsync<int>(sql.ToString(), new { activity_id }) ;
            record.sort = sort + 1;
            sql.Clear();
            sql.Append("INSERT into kl_activity_record(activity_id,form_id,`name`,mobile,`fields`,num, pay_charge,user_id, `status`,flag,props,`role`,order_id,created, sort)")
                .Append(" VALUES(@activity_id, @form_id, @name, @mobile, @fields, @num, @pay_charge,@user_id,@status,@flag,@props,@role,@order_id , @created,@sort);");
            await connection.ExecuteAsync(sql.ToString(), record);

           return new { activity_id, order_id };
        }
    }
}